package com.itfreer.data.check;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.itfreer.data.check.entity.CheckConfigEntity;
import com.itfreer.data.check.entity.CheckHistoryEntity;
import com.itfreer.data.check.entity.CheckHistoryItemEntity;

/**
 * 检查服务类 核心算法，基于ICheck接品进行数据检查
 */
@Component
public class CheckServiceImp implements CheckService, ApplicationContextAware {

	private static ApplicationContext applicationContext;

	@Autowired
	private CheckConfigService checkConfigService;

	@Autowired
	private CheckHistoryService checkHistoryService;

	/**
	 * 数据检查
	 * 
	 * @param info
	 *            检查信息
	 * @param entity
	 *            检查数据
	 * @param checkTypeID
	 *            检查配置
	 * @param tacheid
	 *            检查环节
	 * @return
	 */
	@Override
	public CheckHistoryEntity check(CheckHistoryEntity info, Object entity, String checkTypeID, Integer tacheid) {
		Map<String, Object> where = new HashMap<>();
		where.put("checkType", checkTypeID);
		Map<String, Integer> ordre = new HashMap<>();
		ordre.put("order", 0);
		List<CheckConfigEntity> checkConfigs = checkConfigService.getEntitys(where, ordre);
		return check(info, entity, checkConfigs, tacheid);
	}

	/**
	 * 数据检查
	 * 
	 * @param info
	 *            检查信息
	 * @param entity
	 *            检查数据
	 * @param config
	 *            检查配置
	 * @param tacheid
	 *            检查环节
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public CheckHistoryEntity check(CheckHistoryEntity info, Object entitys, List<CheckConfigEntity> configs,
			Integer tacheid) {
		// 初始化
		if (info.getId() != null) {
			info.setItems(new LinkedHashSet<>());
		}

		// 数据检查
		Boolean all = true;
		for (CheckConfigEntity config : configs) {
			CheckHistoryItemEntity hisItem = assembleCheckHistory(config);
			info.getItems().add(hisItem);
			if (tacheid >= config.getTacheid()) {
				ICheck check = (ICheck) applicationContext.getBean(config.getBeanname());
				if (entitys instanceof List) {
					List<Object> entityObjects = (List<Object>) entitys;
					String result = null;
					for (Object entity : entityObjects) {
						result = check.runCheck(entity, config.getParas());
						if (result != null) {
							break;
						}
					}
					if (result == null) {
						hisItem.setState("检查通过");
					} else {
						hisItem.setState("检查不通过");
						hisItem.setResult(result);
						all = false;
					}
				} else {
					String result = check.runCheck(entitys, config.getParas());
					if (result == null) {
						hisItem.setState("检查通过");
					} else {
						hisItem.setState("检查不通过");
						hisItem.setResult(result);
						all = false;
					}
				}
			}
		}

		// 更新历史
		info.setLastTime(new Date());
		info.setState(all);
		if (all) {
			info.setInfo("数据检查成功");
		} else {
			info.setInfo("数据检查失败");
		}
		if (info.getId() != null) {
			return checkHistoryService.update(info);
		} else {
			info.setId(UUID.randomUUID().toString().replace("-", ""));
			return checkHistoryService.add(info);
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext appContext) throws BeansException {
		applicationContext = appContext;
	}

	/**
	 * 组装历史记录
	 * 
	 * @param checkConfig
	 *            配置数据
	 * @param dataid
	 *            数据实体主键id
	 * @param checkFlag
	 *            检查是否通过
	 * @return
	 */
	private CheckHistoryItemEntity assembleCheckHistory(CheckConfigEntity checkConfig) {
		CheckHistoryItemEntity checkHistory = new CheckHistoryItemEntity();
		// id值
		checkHistory.setId(java.util.UUID.randomUUID().toString().replace("-", ""));
		// 检查时间
		checkHistory.setChecktime(new Date());
		// 检查状态
		checkHistory.setState("未检查");
		// 检查时间
		checkHistory.setChecktime(new Date());

		// 复制配置
		checkHistory.setName(checkConfig.getName());
		checkHistory.setTacheid(checkConfig.getTacheid());
		checkHistory.setTachename(checkConfig.getTachename());
		checkHistory.setOrder(checkConfig.getOrder());
		checkHistory.setType(checkConfig.getType());
		checkHistory.setRule(checkConfig.getRule());
		checkHistory.setRuledesc(checkConfig.getRuledesc());

		return checkHistory;
	}
}